package com.member.mp.web.user;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.member.common.cache.CacheService;
import com.member.common.core.domain.AjaxResult;
import com.member.common.core.domain.R;
import com.member.common.core.page.PageResult;
import com.member.common.core.page.TableDataInfo;
import com.member.common.enums.DeleteEnum;
import com.member.common.enums.OrderDeleteEnum;
import com.member.common.enums.VerificationStatusEnum;
import com.member.common.utils.*;
import com.member.common.utils.fy.HttpUtil;
import com.member.common.utils.fy.SignatureUtils;
import com.member.mp.config.SmsManager;
import com.member.shop.domain.*;
import com.member.shop.dto.*;
import com.member.shop.service.*;
import com.member.shop.vo.UserVo;
import com.member.shop.vo.WriteOffDetailVo;
import com.member.shop.vo.WriteOffVo;
import com.member.system.cache.TokenCache;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

/**
 * 【用户】控制器
 *
 * @author wangxin
 * @version 1.0
 * @date Mon Jul 03 22:06:51 CST 2024
 **/
@RestController
@Slf4j
@Api(value = "用户接口", tags = {"用户接口"})
@RequestMapping("/wx/user")
public class UserController extends SupperController {

    @Resource
    private ISysBizUserService sysBizUserService;
    @Resource
    private ISysBizUserAddressService sysBizUserAddressService;
    @Resource
    private ISysBizAgreementService sysBizAgreementService;
    @Resource
    private ISysBizActivityEnrollService sysBizActivityEnrollService;
    @Resource
    private CacheService cacheService;
    @Resource
    private ISysBizOftenBuyService oftenBuyService;
    @Resource
    private ISysBizShopCertificationService shopCertificationService;
    @Resource
    private ISysBizUserIntegralRecordService integralRecordService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private ISysBizUserInviteService userInviteService;
    @Resource
    private ISysBizRaffleResultsService raffleResultsService;
    @Resource
    private ISysBizUserSignService userSignService;
    @Resource
    private ISysBizTenantAreaService tenantAreaService;
    @Resource
    private ISysBizTenantService sysBizTenantService;
    @Resource
    private ISysBizRegionService sysBizRegionService;
    @Resource
    private ISysBizFeedbackService feedbackService;
    @Resource
    private SmsManager smsManager;
    private static final String UPDATE_PHONE_CODE = "UP_PHONE_";
    public static final String CART_KEY = "CART:";

    
    private String getCartKey() {
        SysBizUser loginUser = getLoginUser();
        Long userId = loginUser.getId();
        Long tenantId = loginUser.getTenantId();

        String key = CART_KEY + tenantId + ":" + userId;
        return key;
    }

    /**
     * 查询登录用户详细信息（修改，新增余额，优惠券数量字段）
     *
     * @return 结果
     */
    @GetMapping("/queryUserById")
    public R<UserVo> queryUserById() {
        UserVo sysBizUser = sysBizUserService.queryUserById(getUserId());// 这里的站点Id 应该实时查询 不然有bug

        String key = getCartKey();
        BoundHashOperations<String, Object, Object> cartMap = stringRedisTemplate.boundHashOps(key);
        // 获取购物车数据
        List<Object> cartList = cartMap.values();
        sysBizUser.setCatNum(cartList.size());
        return R.ok(sysBizUser);
    }

    /**
     * 查询商铺认证列表
     *
     * @return 结果
     */
    @GetMapping("/queryShopCertification")
    public R<PageResult<SysBizShopCertification>> queryShopCertification() {
        try {
            Long userId = getUserId();
            startPage();
            SysBizShopCertification bizShopCertification = new SysBizShopCertification();
            bizShopCertification.setUserId(userId);

            List<SysBizShopCertification> integralRecords = shopCertificationService.selectSysBizShopCertificationList(bizShopCertification);
            TableDataInfo dataTable = getDataTable(integralRecords);
            List<?> rows = dataTable.getRows();
            List<SysBizShopCertification> collect = rows.stream().map(p -> (SysBizShopCertification) p).collect(Collectors.toList());
            return R.ok(new PageResult<>(dataTable.getTotal(), collect));
        } catch (Exception e) {
            e.printStackTrace();

            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 查询商铺认证
     *
     * @return 结果
     */
    @GetMapping("/shopCertification/{id}")
    public R<SysBizShopCertification> queryShopCertification(@PathVariable("id") Long id) {
        try {
            Long userId = getUserId();
            SysBizShopCertification bizShopCertification = shopCertificationService.getById(id);
            if (bizShopCertification.getUserId().equals(userId)) {
                return R.fail("非法请求");
            }
            return R.ok(bizShopCertification);
        } catch (Exception e) {
            e.printStackTrace();

            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 添加常买
     *
     * @param goodsId 商品id
     * @return 结果
     */
    @PostMapping("/addOftenBuy/{goodsId}")
    public R<String> addOftenBuy(@PathVariable("goodsId") Long goodsId) {
        if (goodsId == null) {
            return R.fail("参数错误");
        }
        LambdaQueryWrapper<SysBizOftenBuy> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysBizOftenBuy::getGoodsId, goodsId);
        SysBizUser loginUser = getLoginUser();
        Long userId = loginUser.getId();
        Long tenantId = loginUser.getTenantId();
        queryWrapper.eq(SysBizOftenBuy::getUserId, userId);
        queryWrapper.eq(SysBizOftenBuy::getTenantId, tenantId);
        List<SysBizOftenBuy> list = oftenBuyService.list(queryWrapper);

        if (CollectionUtils.isEmpty(list)) {
            SysBizOftenBuy sysBizOftenBuy = new SysBizOftenBuy();
            sysBizOftenBuy.setTenantId(tenantId);
            sysBizOftenBuy.setUserId(userId);
            sysBizOftenBuy.setAddTime(LocalDateTime.now());
            sysBizOftenBuy.setDeleted(DeleteEnum.NOT_DELETE.getKey());
            sysBizOftenBuy.setCreateTime(new Date());
            sysBizOftenBuy.setUserId(userId);
            sysBizOftenBuy.setUpdateTime(new Date());
            sysBizOftenBuy.setGoodsId(goodsId);
            oftenBuyService.saveOrUpdate(sysBizOftenBuy);
        }
        return R.ok();
    }

    /**
     * 删除常买
     *
     * @param id 常买id
     * @return 结果
     */
    @PostMapping("/deleteOftenBuy/{id}")
    public R<String> deleteOftenBuy(@PathVariable("id") Long id) {
        if (id == null) {
            return R.fail("参数错误");
        }
        Long userId = getUserId();
        SysBizOftenBuy oftenBuy = oftenBuyService.getById(id);

        if (oftenBuy == null || !oftenBuy.getUserId().equals(userId)) {
            return R.fail("非法请求");
        }

        oftenBuyService.removeById(id);

        return R.ok();
    }

    /**
     * 删除常买（New）
     *
     * @param goodsId 商品id
     * @return 结果
     */
    @PostMapping("/delOftenBuy/{goodsId}")
    public R<String> delOftenBuy(@PathVariable("goodsId") Long goodsId) {
        if (goodsId == null) {
            return R.fail("参数错误");
        }
        Long userId = getUserId();
        SysBizOftenBuy oftenBuy = oftenBuyService.getOne(new LambdaQueryWrapper<SysBizOftenBuy>()
                .eq(SysBizOftenBuy::getGoodsId, goodsId)
                .eq(SysBizOftenBuy::getUserId, userId));

        if (oftenBuy == null) {
            return R.fail("非法请求");
        }

        oftenBuyService.removeById(oftenBuy.getId());

        return R.ok();
    }

    /**
     * 申请商铺认证
     *
     * @param shopCertificationDto 商铺认证
     * @return 结果
     */
    @PostMapping("/shopCertification")
    public R<SysBizShopCertification> shopCertification(@RequestBody ShopCertificationDto shopCertificationDto) {
        if (shopCertificationDto == null) {
            return R.fail("参数错误");
        }
        SysBizUser loginUser = getLoginUser();
        Long userId = loginUser.getId();
        Long tenantId = loginUser.getTenantId();
        SysBizShopCertification target = new SysBizShopCertification();
        BeanUtils.copyProperties(shopCertificationDto, target);

        if (target.getId() == null) {
            target.setId(ShortSnowflakeUtils.nextId());
            target.setTenantId(tenantId);
            target.setUserId(userId);

            target.setApplyTime(LocalDateTime.now());
            target.setCertificationStatus(1);
            target.setDeleted(DeleteEnum.NOT_DELETE.getKey());
            target.setCreateTime(new Date());
            target.setUpdateTime(new Date());

        } else {
            SysBizShopCertification sysBizShopCertification = shopCertificationService.selectSysBizShopCertificationById(target.getId());
            if (sysBizShopCertification.getCertificationStatus() == 2 || sysBizShopCertification.getCertificationStatus() == 3) {
                target.setId(sysBizShopCertification.getId());
                target.setCertificationStatus(1);
                target.setTenantId(tenantId);
                target.setUserId(userId);
                target.setApplyTime(LocalDateTime.now());
                target.setUpdateTime(new Date());
                target.setDeleted(DeleteEnum.NOT_DELETE.getKey());
                target.setRemark(null);
            }
        }
        // 根据省市区获取站点ID
        List<SysBizTenantArea> sysBizTenantAreas = tenantAreaService.selectSysBizTenantAreaList(new LambdaQueryWrapper<SysBizTenantArea>()
                .eq(SysBizTenantArea::getProvince, shopCertificationDto.getProvince())
                .eq(SysBizTenantArea::getCity, shopCertificationDto.getCity())
                .eq(SysBizTenantArea::getArea, shopCertificationDto.getArea())
                .eq(SysBizTenantArea::getDeleted, DeleteEnum.NOT_DELETE.getKey())
        );
        if(!CollectionUtils.isEmpty(sysBizTenantAreas)){
            target.setTenantId(sysBizTenantAreas.get(0).getTenantId());
        }
        shopCertificationService.saveOrUpdate(target);
        return R.ok(target);
    }


    /**
     * 撤回商铺认证
     *
     * @param bizShopCertification 认证 (id 、备注)
     * @return 结果
     */
    @PostMapping("/withdrawShopCertification")
    public R<String> withdrawShopCertification(@RequestBody SysBizShopCertification bizShopCertification) {
        Long id = bizShopCertification.getId();
        if (id == null) {
            return R.fail("参数错误");
        }

        Long userId = getUserId();


        SysBizShopCertification byId = shopCertificationService.getById(id);


        if (byId == null) {
            return R.fail("认证不存在");

        }
        if (!userId.equals(byId.getUserId())) {
            return R.fail("非法请求");
        }


        if (byId.getCertificationStatus() != 1) {
            return R.fail("认证状态错误，无法撤回");
        }

        LambdaUpdateWrapper<SysBizShopCertification> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(SysBizShopCertification::getUpdateTime, new Date());
        updateWrapper.set(SysBizShopCertification::getCertificationStatus, 0);
        if (StringUtils.isNotEmpty(bizShopCertification.getRemark())) {
            updateWrapper.set(SysBizShopCertification::getRemark, bizShopCertification.getRemark());

        }
        updateWrapper.eq(SysBizShopCertification::getId, id);
        shopCertificationService.update(updateWrapper);
        return R.ok();
    }

    /**
     * 查询站点信息（经纬度）
     *
     * @param tenantId 站点ID
     * @return　结果
     */
    @GetMapping("/queryTenantInfo/{tenantId}")
    public R<SysBizTenant> queryTenantInfo(@PathVariable("tenantId") Long tenantId) {
        if (tenantId == null) {
            return R.fail("参数错误");
        }
        SysBizTenant bizTenant = sysBizTenantService.getById(tenantId);
        return R.ok(bizTenant);
    }

    /**
     * 修改用户默认站点
     *
     * @param tenantId 站点id
     * @return 结果
     */
    @PostMapping("/updateTenant/{tenantId}")
    public R<String> updateTenant(@PathVariable("tenantId") Long tenantId) {
        if (tenantId == null) {
            return R.fail("参数错误");
        }

        LambdaUpdateWrapper<SysBizUser> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(SysBizUser::getTenantId, tenantId);
        updateWrapper.set(SysBizUser::getUpdateTime, new Date());

        Long userId = getUserId();
        updateWrapper.eq(SysBizUser::getId, userId);

        sysBizUserService.update(updateWrapper);

        SysBizUser byId = sysBizUserService.getById(userId);
        String token = getToken();
        if (byId != null) {
            // 更新cache
            TokenCache.setMpData(token, JSON.toJSONString(byId));
        }

        return R.ok();
    }

    /**
     * 修改登录用户信息
     *
     * @param userUpdateDto 参数
     * @return 结果
     */
    @PostMapping("/updateUser")
    public R<String> updateUser(@RequestBody UserUpdateDto userUpdateDto) {
        LambdaUpdateWrapper<SysBizUser> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.set(StringUtils.isNotBlank(userUpdateDto.getAvatar()), SysBizUser::getAvatar, userUpdateDto.getAvatar());
        updateWrapper.set(StringUtils.isNotBlank(userUpdateDto.getNickName()), SysBizUser::getNickName, userUpdateDto.getNickName());
        updateWrapper.set(SysBizUser::getUpdateTime, new Date());
        updateWrapper.set(StringUtils.isNotBlank(userUpdateDto.getProvince()), SysBizUser::getProvince, userUpdateDto.getProvince());
        updateWrapper.set(StringUtils.isNotBlank(userUpdateDto.getCity()), SysBizUser::getCity, userUpdateDto.getCity());
        updateWrapper.set(userUpdateDto.getBirthday() != null, SysBizUser::getBirthday, userUpdateDto.getBirthday());
        updateWrapper.set(SysBizUser::getUpdateTime, new Date());
        updateWrapper.set(userUpdateDto.getSex() != null, SysBizUser::getSex, userUpdateDto.getSex());
        updateWrapper.set(StringUtils.isNotBlank(userUpdateDto.getAppVersion()), SysBizUser::getAppVersion, userUpdateDto.getAppVersion());
        updateWrapper.set(StringUtils.isNotBlank(userUpdateDto.getPhoneSystem()), SysBizUser::getPhoneSystem, userUpdateDto.getPhoneSystem());

        updateWrapper.eq(SysBizUser::getId, getUserId());

        sysBizUserService.update(updateWrapper);
        return R.ok();
    }

    /**
     * 修改密码 修改完清除token直接跳登录页
     *
     * @param userUpdateDto 参数
     * @return 结果
     */
    @PostMapping("/updateUserPassword")
    public R<String> updateUserPassword(@RequestBody UserUpdatePwdDto userUpdateDto) {
        Long userId = getUserId();
        SysBizUser sysBizUser = sysBizUserService.getById(userId);
        if (!SecurityUtils.matchesPassword(userUpdateDto.getOldPassword(), sysBizUser.getPassword())) {
            return R.fail("旧密码错误");
        }
        sysBizUserService.update(new LambdaUpdateWrapper<>(SysBizUser.class).eq(SysBizUser::getId, userId).set(SysBizUser::getPassword, SecurityUtils.encryptPassword(userUpdateDto.getNewPassword())));
        TokenUtils.removeToken(getRequest(), getToken());
        return R.ok();
    }

    /**
     * 发送修改手机号验证码
     *
     * @param phoneNum 手机号
     * @return 结果
     */
    @PostMapping("/verificationCodeByPhone/{phoneNum}")
    public R<String> verificationCodeByPhone(@PathVariable String phoneNum) throws Exception {
        try {
            // 参数校验
            if (org.apache.commons.lang3.StringUtils.isBlank(phoneNum)) {
                return R.fail("手机号不能为空");
            }
            if (!phoneNum.matches("^1[3-9]\\d{9}$")) {
                return R.fail("手机号格式不正确");
            }

            // 生成6位验证码
            String code = String.format("%06d", ThreadLocalRandom.current().nextInt(100000, 1000000));

            // 清除旧验证码
            String cacheKey = UPDATE_PHONE_CODE + phoneNum;
            if (cacheService.exists(cacheKey)) {
                cacheService.remove(cacheKey);
            }

            // 设置新验证码（包含原子性设置）
            if (cacheService.setNX(cacheKey, code, 300)) { // 5分钟
                // 实际发送短信
                try {
                    smsManager.sendCode(code, phoneNum);
                } catch (Exception e) {
                    cacheService.remove(cacheKey);
                    log.error("短信发送失败: {}", phoneNum, e);
                    return R.fail("短信发送失败，请稍后重试");
                }
                return R.ok();
            }
            return R.fail("请求过于频繁，请稍后再试");
        } catch (Exception e) {
            log.error("验证码发送异常: {}", phoneNum, e);
            return R.fail("系统繁忙，请稍后重试");
        }
    }

    /**
     * 修改手机号码，修改完清除token跳转登录页
     *
     * @param userUpdatePhoneDto 参数
     * @return 结果
     */
    @PostMapping("/updatePhone")
    public R<String> updatePhone(@RequestBody UserUpdatePhoneDto userUpdatePhoneDto) {

        try {
            Long userId = getUserId();
            if (!cacheService.exists(UPDATE_PHONE_CODE + userUpdatePhoneDto.getPhoneNumber())
                    || !userUpdatePhoneDto.getVerificationCode().equals(cacheService.get(UPDATE_PHONE_CODE + userUpdatePhoneDto.getPhoneNumber()) + "")) {
                return R.fail("验证码错误");
            }

            SysBizUser sysBizUser = sysBizUserService.getById(userId);
            if (sysBizUser.getUserPhone().equals(userUpdatePhoneDto.getPhoneNumber())) {
                return R.fail("当前手机号和登录手机号一致");
            }
            List<SysBizUser> list = sysBizUserService.list(new LambdaQueryWrapper<SysBizUser>()
                    .eq(SysBizUser::getUserPhone, userUpdatePhoneDto.getPhoneNumber())
                    .eq(SysBizUser::getDeleted, OrderDeleteEnum.NOT_DELETE.getKey()));
            if (!CollectionUtils.isEmpty(list)) {
                return R.fail("当前手机号已注册");
            }
            sysBizUserService.update(new LambdaUpdateWrapper<SysBizUser>()
                    .set(SysBizUser::getUserPhone, userUpdatePhoneDto.getPhoneNumber())
//                    .set(SysBizUser::getPassword, SecurityUtils.encryptPassword(userUpdatePhoneDto.getNewPassword()))
                    .eq(SysBizUser::getId, userId));
            cacheService.remove(UPDATE_PHONE_CODE + userUpdatePhoneDto.getPhoneNumber());
            TokenUtils.removeToken(getRequest(), getToken());
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();

            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 查询用户积分 （type=0 or null 全部积分 ，有值指定类型积分）
     *
     * @return 结果
     */
    @GetMapping("/queryScore")
    public R<PageResult<SysBizUserIntegralRecord>> queryScore(@RequestParam(value = "type", required = false) Integer type) {
        try {
            SysBizUser loginUser = getLoginUser();
            Long userId = loginUser.getId();
            Long tenantId = loginUser.getTenantId();

            startPage();
            SysBizUserIntegralRecord sysBizUserIntegralRecord = new SysBizUserIntegralRecord();
            sysBizUserIntegralRecord.setUserId(userId);
            if (type != null) {
                sysBizUserIntegralRecord.setBussType(type);
            }
            sysBizUserIntegralRecord.setTenantId(tenantId);

            List<SysBizUserIntegralRecord> integralRecords = integralRecordService.selectSysBizUserIntegralRecordList(sysBizUserIntegralRecord);
            TableDataInfo dataTable = getDataTable(integralRecords);
            List<?> rows = dataTable.getRows();
            List<SysBizUserIntegralRecord> collect = rows.stream().map(p -> (SysBizUserIntegralRecord) p).collect(Collectors.toList());
            return R.ok(new PageResult<>(dataTable.getTotal(), collect));
        } catch (Exception e) {
            e.printStackTrace();

            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 查询用户邀请记录
     *
     * @return 结果
     */
    @GetMapping("/queryInviteList")
    public R<PageResult<SysBizUserInvite>> queryInviteList() {
        try {
            Long userId = getUserId();
            startPage();
            SysBizUserInvite userInvite = new SysBizUserInvite();
            userInvite.setInviteUserId(userId);
            List<SysBizUserInvite> integralRecords = userInviteService.selectSysBizUserInviteList(userInvite);
            TableDataInfo dataTable = getDataTable(integralRecords);
            List<?> rows = dataTable.getRows();
            List<SysBizUserInvite> collect = rows.stream().map(p -> (SysBizUserInvite) p).collect(Collectors.toList());
            return R.ok(new PageResult<>(dataTable.getTotal(), collect));
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 查询用户签到（最近一个月）
     *
     * @return 结果
     */
    @GetMapping("/querySign")
    public R<List<SysBizUserSign>> querySign() {
        try {
            SysBizUser loginUser = getLoginUser();
            Long userId = loginUser.getId();
            Long tenantId = loginUser.getTenantId();

            SysBizUserSign bizUserSign = new SysBizUserSign();
            bizUserSign.setUserId(userId);
            bizUserSign.setTenantId(tenantId);
            LambdaQueryWrapper<SysBizUserSign> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysBizUserSign::getUserId, userId);
            LocalDate minSignDate = LocalDate.now().withDayOfMonth(1);
            LocalDate maxSignDate = minSignDate.plusMonths(1);
            queryWrapper.ge(SysBizUserSign::getSignDate, minSignDate);
            queryWrapper.lt(SysBizUserSign::getSignDate, maxSignDate);
            queryWrapper.orderByAsc(SysBizUserSign::getSignDate);
            List<SysBizUserSign> signs = userSignService.selectSysBizUserSignList(queryWrapper);

            return R.ok(signs);


        } catch (Exception e) {
            e.printStackTrace();

            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }


    /**
     * 插入用户反馈
     *
     * @return 结果
     */
    @PostMapping("/insertFeedback")
    public R<SysBizFeedback> insertFeedback(@RequestBody SysBizFeedback feedback) {
        try {
            SysBizUser loginUser = getLoginUser();
            Long userId = loginUser.getId();
            Long tenantId = loginUser.getTenantId();

            feedback.setUserId(userId);
            feedback.setTenantId(tenantId);
            feedback.setCreateTime(new Date());
            feedback.setStatus(0);
            feedback.setUpdateTime(new Date());

            feedbackService.insertSysBizFeedback(feedback);
            return R.ok(feedback);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 查询用户反馈结果
     *
     * @return 结果
     */
    @GetMapping("/queryFeedback")
    public R<PageResult<SysBizFeedback>> queryFeedback() {
        try {
            startPage();
            LambdaQueryWrapper<SysBizFeedback> queryWrapper = new LambdaQueryWrapper<>();
            SysBizUser loginUser = getLoginUser();
            Long userId = loginUser.getId();
            Long tenantId = loginUser.getTenantId();
            queryWrapper.eq(SysBizFeedback::getUserId, userId);
            queryWrapper.eq(SysBizFeedback::getTenantId, tenantId);
            List<SysBizFeedback> integralRecords = feedbackService.selectSysBizFeedbackList(queryWrapper);
            TableDataInfo dataTable = getDataTable(integralRecords);
            List<?> rows = dataTable.getRows();
            List<SysBizFeedback> collect = rows.stream().map(p -> (SysBizFeedback) p).collect(Collectors.toList());
            return R.ok(new PageResult<>(dataTable.getTotal(), collect));
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 插入用户签到
     *
     * @return 结果
     */
    @PostMapping("/insertSign")
    public R<SysBizUserSign> insertSign(@RequestBody SysBizUserSign sysBizUserSign) {
        try {
            SysBizUser loginUser = getLoginUser();
            Long userId = loginUser.getId();
            Long tenantId = loginUser.getTenantId();
            sysBizUserSign.setUserId(userId);
            sysBizUserSign.setTenantId(tenantId);
            sysBizUserSign.setSignTime(LocalDateTime.now());
            sysBizUserSign.setCreateTime(new Date());
            sysBizUserSign.setStatus(1L);
            sysBizUserSign.setUpdateTime(new Date());

            // 增加积分
            SysBizUser byId = sysBizUserService.getById(userId);

            integralRecordService.addIntegralRecord(byId, "6");

            userSignService.insertSysBizUserSign(sysBizUserSign);
            return R.ok(sysBizUserSign);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 查询用户奖品
     *
     * @param type null 全部 2 优惠券  3 实物奖
     * @return 结果
     */
    @GetMapping("/queryAward")
    public R<PageResult<SysBizRaffleResults>> queryAward(@RequestParam(value = "type", required = false) Integer type) {
        try {
            SysBizUser loginUser = getLoginUser();
            Long userId = loginUser.getId();
            Long tenantId = loginUser.getTenantId();
            startPage();
            SysBizRaffleResults bizRaffleResults = new SysBizRaffleResults();
            bizRaffleResults.setUserId(userId);
            bizRaffleResults.setTenantId(tenantId);
            if (type != null) {

                bizRaffleResults.setPrizeType(type);
            }
            List<SysBizRaffleResults> integralRecords = raffleResultsService.selectSysBizRaffleResultsList(bizRaffleResults);
            TableDataInfo dataTable = getDataTable(integralRecords);
            List<?> rows = dataTable.getRows();
            List<SysBizRaffleResults> collect = rows.stream().map(p -> (SysBizRaffleResults) p).collect(Collectors.toList());
            return R.ok(new PageResult<>(dataTable.getTotal(), collect));


        } catch (Exception e) {
            e.printStackTrace();

            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 领取奖品
     *
     * @return 结果
     */
    @PostMapping("/receiveAward/{id}")
    public R<String> receiveAward(@PathVariable Long id) {

        try {
            Long userId = getUserId();
            SysBizRaffleResults byId = raffleResultsService.getById(id);
            if (!byId.getUserId().equals(userId)) {
                R.fail("身份信息不匹配，无法领取");
            }
            Integer extractStatus = byId.getExtractStatus();
            if (extractStatus != 0) {
                R.fail("奖品已领取");
            }
            raffleResultsService.updateExtractStatus(id, 1);
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 查询用户收货地址
     *
     * @return 结果
     */
    @GetMapping("/queryAddress")
    public R<List<SysBizUserAddress>> queryAddress() {
        try {
            SysBizUser loginUser = getLoginUser();
            Long userId = loginUser.getId();
            Long tenantId = loginUser.getTenantId();

            SysBizTenantArea sysBizTenantArea = new SysBizTenantArea();
            sysBizTenantArea.setTenantId(tenantId);
            sysBizTenantArea.setDeleted(DeleteEnum.NOT_DELETE.getKey());
            List<SysBizTenantArea> sysBizTenantAreas = tenantAreaService.selectSysBizTenantAreaList(sysBizTenantArea);
            Map<String, SysBizTenantArea> scopeCache = new HashMap<>();
            if (!CollectionUtils.isEmpty(sysBizTenantAreas)) {
                scopeCache = sysBizTenantAreas.stream().collect(Collectors.toMap(p -> p.getProvince() + ":" + p.getCity() + ":" + p.getArea(), v -> v));
            }
            LambdaQueryWrapper<SysBizUserAddress> sysBizUserAddressLambdaQueryWrapper = new LambdaQueryWrapper<>();
            sysBizUserAddressLambdaQueryWrapper.eq(SysBizUserAddress::getUserId, userId);
            sysBizUserAddressLambdaQueryWrapper.eq(SysBizUserAddress::getTenantId, tenantId);
            sysBizUserAddressLambdaQueryWrapper.orderByDesc(SysBizUserAddress::getStatus);
            sysBizUserAddressLambdaQueryWrapper.orderByDesc(SysBizUserAddress::getId);
            List<SysBizUserAddress> sysBizUserAddresses = sysBizUserAddressService.selectSysBizUserAddressList(sysBizUserAddressLambdaQueryWrapper);
            if (!CollectionUtils.isEmpty(sysBizUserAddresses)) {
                for (SysBizUserAddress address : sysBizUserAddresses) {
                    String key = address.getProvince() + ":" + address.getCity() + ":" + address.getArea();
                    address.setValid(0);
                    if (scopeCache.containsKey(key)) {
                        address.setValid(1);
                    }
                }
            }
            return R.ok(sysBizUserAddresses);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 查询用户收货地址详情
     *
     * @param id 地址id
     * @return 结果
     */
    @GetMapping("/queryAddressById/{id}")
    public R<SysBizUserAddress> queryAddressById(@PathVariable Long id) {
        try {
            SysBizUserAddress sysBizUserAddress = sysBizUserAddressService.selectSysBizUserAddressById(id);
            return R.ok(sysBizUserAddress);
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }





    @Resource
    private ISysBizShopCertificationService sysBizShopCertificationService;


    /**
     * 删除用户收货地址
     *
     * @param id 地址id
     * @return 结果
     */
    @PostMapping("/deleteAddress/{id}")
    public R<String> deleteAddress(@PathVariable Long id) {
        try {
            sysBizUserAddressService.removeById(id);
            sysBizUserAddressService.removeErpAddress(id);
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 批量删除用户收货地址
     *
     * @return 结果
     */
    @PostMapping("/batchDeleteAddress")
    public R<String> batchDeleteAddress(@RequestBody List<Long> ids) {
        try {
            if (!CollectionUtils.isEmpty(ids)) {
                ids.forEach(id -> {
                    sysBizUserAddressService.removeById(id);
                    sysBizUserAddressService.removeErpAddress(id);
                });
            }
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 修改用户收货地址
     *
     * @param sysBizUserAddress 参数
     * @return 结果
     */
    @PostMapping("/updateAddress")
    public R<String> updateAddress(@RequestBody SysBizUserAddress sysBizUserAddress) {
        try {
            sysBizUserAddressService.updateAddress(sysBizUserAddress);
            sysBizUserAddressService.updateAddressErp(sysBizUserAddress,getUserId());
            return R.ok();
        } catch (Exception e) {
            e.printStackTrace();

            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 新增用户收货地址
     *
     * @param sysBizUserAddress 参数
     * @return 结果
     */
    @PostMapping("/insertAddress")
    public R<String> insertAddress(@RequestBody SysBizUserAddress sysBizUserAddress) {
        try {
            Long tenantId = getTenantId();
            sysBizUserAddress.setTenantId(tenantId);

            List<SysBizUserAddress> sysBizUserAddresses = sysBizUserAddressService.selectSysBizUserAddressList(new LambdaQueryWrapper<SysBizUserAddress>().eq(SysBizUserAddress::getUserId, getUserId()).orderByDesc(SysBizUserAddress::getStatus).orderByDesc(SysBizUserAddress::getId));
            if (CollectionUtils.isEmpty(sysBizUserAddresses)) {
                sysBizUserAddress.setStatus(1);
            }
            sysBizUserAddress.setCreateTime(new Date());
            sysBizUserAddress.setUpdateTime(new Date());
            sysBizUserAddress.setUserId(getUserId());
            sysBizUserAddressService.insertAddress(sysBizUserAddress);
            sysBizUserAddressService.insertAddressErp(sysBizUserAddress,getUserId());
            return R.ok();

        } catch (Exception e) {
            e.printStackTrace();

            log.error(e.getMessage());
            return R.fail(e.getMessage());
        }
    }

    /**
     * 查询协议
     *
     * @return 结果
     */
    @GetMapping("/queryAgreement")
    public R<SysBizAgreement> queryAgreement() {
        LambdaQueryWrapper<SysBizAgreement> queryWrapper = new LambdaQueryWrapper<>();
        List<SysBizAgreement> list = sysBizAgreementService.list(queryWrapper);
        if (CollectionUtils.isEmpty(list)) {
            return R.fail("协议未配置");
        }
        SysBizAgreement sysBizAgreement = list.get(0);
        return R.ok(sysBizAgreement);
    }

    /**
     * 管理员：核销二维码（无效）
     *
     * @param writeOffDto 二维码里的id原封不动传过来
     * @return
     */
    @PostMapping("/writeOff")
    public R<Long> writeOff(@RequestBody WriteOffDto writeOffDto) {
        try {
            Long id = Long.parseLong(writeOffDto.getCode());
            SysBizActivityEnroll sysBizActivityEnroll = sysBizActivityEnrollService.selectSysBizActivityEnrollById(id);
            if (sysBizActivityEnroll == null) {
                return R.fail("未找到订单");
            }
            if (Objects.equals(sysBizActivityEnroll.getVerificationStatus(), VerificationStatusEnum.VERIFIED.getKey())) {
                return R.fail("当前核销码已核销");
            }
            sysBizActivityEnroll.setVerificationStatus(VerificationStatusEnum.VERIFIED.getKey());
            sysBizActivityEnroll.setWriteOffUser(getUserId());
            sysBizActivityEnroll.setWriteOffTime(DateUtils.getNowDate());
            sysBizActivityEnrollService.updateById(sysBizActivityEnroll);
            return R.ok(sysBizActivityEnroll.getId());
        } catch (Exception e) {
            return R.fail("二维码错误");
        }
    }

    /**
     * 管理员：查询核销记录（带分页）（无效）
     *
     * @return
     */
    @PostMapping("/queryWriteOff")
    public R<PageResult<WriteOffVo>> queryWriteOff() {
        startPage();
        LambdaQueryWrapper<SysBizActivityEnroll> sysBizActivityEnrollLambdaQueryWrapper = new LambdaQueryWrapper<>();
        sysBizActivityEnrollLambdaQueryWrapper.eq(SysBizActivityEnroll::getWriteOffUser, getUserId());
        sysBizActivityEnrollLambdaQueryWrapper.orderByDesc(SysBizActivityEnroll::getWriteOffTime);
        List<SysBizActivityEnroll> sysBizActivityEnrolls = sysBizActivityEnrollService.selectSysBizActivityEnrollList(sysBizActivityEnrollLambdaQueryWrapper);
        TableDataInfo dataTable = getDataTable(sysBizActivityEnrolls);
        List<?> rows = dataTable.getRows();
        ArrayList<WriteOffVo> item = new ArrayList<>();
        for (Object row : rows) {
            SysBizActivityEnroll sysBizActivity = (SysBizActivityEnroll) row;
            WriteOffVo target = new WriteOffVo();
            BeanUtils.copyProperties(sysBizActivity, target);
            SysBizUser sysBizUser = sysBizUserService.selectSysBizUserById(sysBizActivity.getUserId());
            target.setUserName(StringUtils.isBlank(sysBizUser.getNickName()) ? "默认昵称" : sysBizUser.getNickName());
            target.setPhone(sysBizUser.getUserPhone());
            item.add(target);
        }
        return R.ok(new PageResult<>(dataTable.getTotal(), item));
    }

    /**
     * 查询核销详情（无效）
     *
     * @param id 报名订单id
     * @return
     */
    @GetMapping("/queryWriteOffById/{id}")
    public R<WriteOffDetailVo> queryWriteOffById(@PathVariable Long id) {
        WriteOffDetailVo writeOffDetailVo = sysBizActivityEnrollService.queryWriteOffById(id, getUserId());
        return R.ok(writeOffDetailVo);
    }

    /**
     * 查询该用户的销售经理
     *
     * @param
     * @return
     */
    @GetMapping("/querySalesUserPhone")
    public R<SysBizUser> querySalesUserPhone() {
        Long id = getUserId();
        //通过自己id 查找销售经理id
        SysBizUser sysBizUser = sysBizUserService.selectSysBizUserById(id);
        if (sysBizUser.getSalesUserId() == null) {
            return R.fail("该用户待认证");
        }

        //查找销售经理详情
        List<SysBizUser> sysBizUsers = sysBizUserService.selectSysBizUserList(new LambdaQueryWrapper<SysBizUser>()
                .eq(SysBizUser::getId, sysBizUser.getSalesUserId())
                .eq(SysBizUser::getDeleted, 0));
        SysBizUser sysBizUser1;
        if (!CollectionUtils.isEmpty(sysBizUsers)) {
            sysBizUser1 = sysBizUsers.get(0);
        } else {
            return R.fail("未找到销售经理");
        }
        return R.ok(sysBizUser1);
    }

    /**
     * 查询街道信息数据
     *
     * @param fatherCode fatherCode
     * @return 街道列表数据
     */
    @GetMapping("/queryStreetInfo/{fatherCode}")
    public R<List<SysBizRegion>> querySalesUserPhone(@PathVariable String fatherCode) {
        if (StringUtils.isEmpty(fatherCode)) {
            return R.fail("参数不能为空");
        }
        List<SysBizRegion> regionList = sysBizRegionService.selectSysBizRegionList(new LambdaQueryWrapper<SysBizRegion>()
                .eq(SysBizRegion::getFathercode, fatherCode));
        return R.ok(regionList);
    }

}
